/* SinaWatch sdk */
(function ($) {
    var SinaWatch = function () {
        this.host = 'http://connect.monitor.sina.com.cn';
    };

    SinaWatch.prototype.bind_auth = function (kid, passwd) {
        this.kid = kid;
        this.passwd = passwd;
    }

    SinaWatch.prototype.hash = function (request, settings, self) {
        var content_md5 = '';
        if (settings.type == 'POST') {
            content_md5 = md5(settings.data);
            request.setRequestHeader('Content-Md5', content_md5);
        }

        var expires = new Date().getTime() / 1000 + 60 * 30;
        request.setRequestHeader('Expires', expires);

        var canonicalizedamzheaders = '';
        var canonicalizedresource = settings.url.substring(self.host.length, settings.url.length);

        var content_type = settings.contentType;
        if (settings.type == 'POST' && settings.data == '') {
            content_type = '';
        }

        var stringtosign = settings.type +
            '\n' + content_md5 +
            '\n' + content_type +
            '\n' + expires +
            '\n' + canonicalizedamzheaders + canonicalizedresource;

        ssig = b64_hmac_sha1(self.passwd, stringtosign);
        ssig = ssig.substring(5, 15);
        // It's not a good idea though, user may know about it;
        request.setRequestHeader('Authorization', 'sinawatch ' + self.kid + ':' + ssig);
    }

    SinaWatch.prototype.call = function (options) {
        options['done'] = options['done'] || function (data) {
        };
        options['error'] = options['error'] || function (data) {
        };
        options['always'] = options['always'] || function () {
        };

        var action = options['action'] || window.location.href;
        var api = this.host + action;

        var method = options['method'] || 'post';
        var data = options['data'] || {};

        var kid = this.kid;
        var passwd = this.passwd;
        var self = this;

        return $.ajax({
            type: method,
            url: api,
            data: data,
            beforeSend: function (request, settings) {
                self.hash(request, settings, self)
            }
        })
            .done(function (data, statue, jqXHR) {
                if (typeof data == 'string') {
                    try {
                        data = $.parseJSON(data);
                    } catch (err) {
                        data = {
                            code: -2,
                            message: 'could not parse json\n' + data,
                            data: null
                        };

                        console.log('[api:error]' + action);
                        console.log(data);
                        options['error'](data);
                        return;
                    }
                }

                if (data.code == 0) {
//                    console.log('[api:done]' + action);
//                    console.log(data.data);
                    options['done'](data.data, data.message);
                } else {
                    console.log('[api:error]' + action);
                    console.log(data);
                    options['error'](data);
                }
            })
            .fail(function (data) {
                data = {
                    code: -1,
                    message: data.statusText + '\n' + data.responseText,
                    data: null
                };

                console.log('[api:fail]' + action);
                console.log(data);

                /* user may hate dialog! */
                options['error'](data);
            })
            .always(function () {
                options['always']();
            })
    };

    SinaWatch.prototype.post = function (options) {
        options['method'] = 'post';
        return this.call(options);
    };

    SinaWatch.prototype.get = function (options) {
        options['method'] = 'get';
        return this.call(options);
    };

    $.SinaWatch = SinaWatch;
})(jQuery);